#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @who:   spacelacc
# @date:  2025/04/03
# @func:  Custom tableviews for 'data confirm', 'data shown'
# @ver:   V1


from PySide6.QtGui     import QPainter, QPen
from PySide6.QtCore    import Qt, QModelIndex, QPoint
from PySide6.QtCore    import QAbstractTableModel
from PySide6.QtWidgets import QTableView, QStyledItemDelegate
import os
 
#from PySide6.QtWidgets import QApplication, QWidget
#from customcontainer   import CustomVBox


class CustomTableModel(QAbstractTableModel):

    def __init__(self, data=[]):
        super().__init__()
        self._data = data
        self.headers = [
            'Serial',  'Selected', 'SourceKind', 'SourceAddr',
            'Param1',  'Param2',   'Param3',     'Param4',
            'Param5',  'Param6',   'Param7',     'Param8',
            'fzeval',  'exeval',   'fzsqrs',     'exsqrs',
        ]

    def rowCount(self, parent=QModelIndex()):
        if not self._data:
            return 0
        return len(self._data)

    def columnCount(self, parent=QModelIndex()):
        if not self._data:
            return 0
        if not self._data[0]:
            return 0
        return len(self._data[0])

    def headerData(self, section, orient, role):
        if section < 0 or section >= len(self.headers):
            return None
        return self.headers[section]

    def data(self, index, role=Qt.DisplayRole):
        row = index.row()
        col = index.column()

        if role == Qt.DisplayRole:
            if isinstance(self._data[row][col], float):
                return '{:.5f}'.format(self._data[row][col])
            elif col == 2:  # the column of source kind
                return 'source kind'
            elif col == 3:  # the column of source addr
                return os.path.basename(self._data[row][col])
            else:
                return str(self._data[row][col])
        elif role == Qt.CheckStateRole:
            if self._data[row][1]:
                return Qt.Checked
            else:
                return Qt.Unchecked
        elif role == Qt.TextAlignmentRole:
            return Qt.AlignVCenter
        else:
            return None

    def appendData(self, data):
        # 1. Check for parameters
        if not data:
            return

        # 2. Now, do the append
        currsize = len(self._data)
        datasize = len(data)
        self.beginInsertRows(QModelIndex(), currsize, currsize+datasize-1)
        for item in data:
            self._data.append(item)
        self.endInsertRows()

    def insertData(self, pos, data):
        # 1. Check for parameters
        if not data:
            return
        if pos < 0 or pos >= len(self._data):
            self.appendData(data)
            return

        # 2. Now, do the insertion
        nrows = len(data)
        self.beginInsertRows(QModelIndex(), pos, pos+nrows-1)
        for i in range(nrows):
            self._data.insert(pos+i, data[i])
        self.endInsertRows()

    def removeData(self, pos, nrows):
        # 1. Check for parameters
        if nrows <= 0:
            return
        if pos < 0 or pos >= len(self._data):
            return
        if pos+nrows > len(self._data):
            nrows = len(self._data)-pos

        # 2. Now, do the remove
        self.beginRemoveRows(QModelIndex(), pos, pos+nrows-1)
        for i in range(nrows):
            del self._data[pos+nrows-1-i]
        self.endRemoveRows()

    # Reconstruct model data:
    def renewData(self, data):
        self.beginResetModel()
        self._data.clear()
        self._data.extend(data)
        self.endResetModel()

    # Update data of 'model' (insert, append)
    def updateData(self, data):
        # 1. Check for parameters
        if not data:
            return

        # 2. Check for repetition
        purified = []
        for item in data:
            if item not in self._data:
                purified.append(item)

        for item in purified:
            print(item)

        # 3. Now, do update
        self.appendData(purified)
#       self.insertData(len(self._data), purified)


class CustomTableDelegate(QStyledItemDelegate):
    def __init__(self):
        super().__init__()

    def paint(self, painter, option, index):
        painter.save()
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        painter.setRenderHint(QPainter.RenderHint.TextAntialiasing)
        painter.setPen(QPen(Qt.black, 2))

#       painter.drawRect(option.rect.x(), option.rect.y(), option.rect.width(), option.rect.height())

        if index.column() == 1:
            w = option.rect.width()
            h = option.rect.height()
            l = option.rect.height() / 4
            bx = option.rect.x()
            by = option.rect.y()
            ox = bx + 0.5*w - 0.5*l
            oy = by + 0.5*h - 0.5*l
            pt1 = QPoint(ox, oy+l/3)
            pt2 = QPoint(ox+l/3, oy+l)
            pt3 = QPoint(ox+l, oy)
            # draw the rectangle of checkbox
            painter.drawRect(bx+0.5*w-0.25*h, by+0.25*h, 0.5*h, 0.5*h)
            data = index.data(Qt.CheckStateRole)
            if data == Qt.Checked:
                # draw the check symbol
                painter.drawPolyline([pt1, pt2, pt3])
        else:
            value = index.data(Qt.DisplayRole)
            painter.drawText(option.rect, Qt.AlignCenter, value)

        painter.restore()


class CustomTableView(QTableView):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.model = CustomTableModel()
        self.delegate = CustomTableDelegate()
        self.setModel(self.model)
        self.setItemDelegate(self.delegate)
        self.horizontalHeader().setVisible(True)
#       self.resizeColumnsToContents()

    # Do minor or major changes of data, if there are data already,
    # these data are still kept, and won't be discarded.
    def updateTableView(self, data):
        # 1. Check for data, if no data, do nothing
        if not data:
            return
        # 2. Call for model to update data and do update tableview.
        self.model.updateData(data)

    # Reset model's data, if there are data, they are discarded.
    def renewTableView(self, data):
        # 1. Check for data, if no data, do nothing.
        if not data:
            return
        # 2. Call for model to reconstruct model data.
        self.model.renewData(data)


#data1 = [
#    ['2411001', True, 0, '/home/clrc/excel', 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 3.0, 4.0, 5.0],
#    ['2411002', True, 0, '/home/clrc/excel', 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 3.0, 4.0, 5.0],
#    ['2411003', True, 0, '/home/clrc/excel', 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 3.0, 4.0, 5.0],
#]
#
#data2 = [
#    ['2411004', True, 0, '/home/clrc/excel', 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 3.0, 4.0, 5.0],
#    ['2411005', True, 0, '/home/clrc/excel', 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 3.0, 4.0, 5.0],
#]
#app = QApplication()
#win = QWidget()
#win.resize(1000, 650)
#
#win1 = CustomTableView(data1)
#win1.updateTableView(data2)
##model1 = CustomTableModel(data1)
##win1.setModel(model1)
##model1.updateData(data2)
#
#win2 = CustomTableView(data2)
##model2 = CustomTableModel(data2)
##win2.setModel(model2)
##win2.renewTableView(data2)
#
#ctwin = CustomVBox(win)
#ctwin.addWidget(win1)
#ctwin.addWidget(win2)
#
#win.show()
#app.exec()
